package com.fengchao.api.service;


import com.alibaba.fastjson.JSON;
import com.fengchao.api.config.Constant;
import com.fengchao.api.dao.cfg.CfgPaymentMapper;
import com.fengchao.api.dao.cfg.CfgRegionMapper;
import com.fengchao.api.dao.cfi.CfiConcertCrowdfundingPayBackMapper;
import com.fengchao.api.dao.cfi.CfiConcertCrowdfundingSingalMapper;
import com.fengchao.api.dao.odr.OdrOrderItemsMapper;
import com.fengchao.api.dao.odr.OdrOrderMapper;
import com.fengchao.api.dao.odr.OdrTicketInfoMapper;
import com.fengchao.api.dao.pfm.PfmPerformanceSingleMapper;
import com.fengchao.api.dao.pfm.PfmPerformanceTicketMapper;
import com.fengchao.api.dao.pfm.PfmPerformanceTotalMapper;
import com.fengchao.api.dao.usr.UsrDeliveryAddressMapper;
import com.fengchao.api.dao.usr.UsrTicketInspectorMapper;
import com.fengchao.model.cfg.CfgPayment;
import com.fengchao.model.cfg.CfgRegion;
import com.fengchao.model.cfi.CfiConcertCrowdfundingPayBack;
import com.fengchao.model.cfi.CfiConcertCrowdfundingSingal;
import com.fengchao.model.entity.Crowdfunding;
import com.fengchao.model.entity.comm.CustomBizException;
import com.fengchao.model.odr.OdrOrder;
import com.fengchao.model.odr.OdrOrderItems;
import com.fengchao.model.odr.OdrTicketInfo;
import com.fengchao.model.pfm.PfmPerformanceTicket;
import com.fengchao.model.pfm.PfmPerformanceTotal;
import com.fengchao.model.usr.UsrDeliveryAddress;
import com.fengchao.model.usr.UsrTicketInspector;
import com.fengchao.util.common.DateUtil;
import com.fengchao.util.common.MailTools;
import com.fengchao.util.encrypt.Md5;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

import static com.fengchao.api.config.Constant.*;
import static com.fengchao.util.common.DateUtil.computeTimestamp;


/**
 * Created by wangnian on 2016/6/20.
 */
@Service
public class OdrService {

    @Autowired
    private OdrOrderMapper odrOrderMapper;
    @Autowired
    private OdrOrderItemsMapper odrOrderItemsMapper;
    @Autowired
    private CfiConcertCrowdfundingPayBackMapper cfiConcertCrowdfundingPayBackMapper;
    @Autowired
    private CfiConcertCrowdfundingSingalMapper cfiConcertCrowdfundingSingalMapper;
    @Autowired
    private UsrDeliveryAddressMapper usrDeliveryAddressMapper;
    @Autowired
    private OdrTicketInfoMapper odrTicketInfoMapper;
    @Autowired
    private CfgPaymentMapper cfgPaymentMapper;
    @Autowired
    private MailTools mailTools;
    @Autowired
    private UsrTicketInspectorMapper usrTicketInspectorMapper;
    @Autowired
    private PfmPerformanceTicketMapper pfmPerformanceTicketMapper;
    @Autowired
    private PfmPerformanceTotalMapper pfmPerformanceTotalMapper;
    @Autowired
    private CfgRegionMapper cfgRegionMapper;
    @Autowired
    private PfmPerformanceSingleMapper pfmPerformanceSingleMapper;

    private static Logger logger = LoggerFactory.getLogger(OdrService.class);

    /**
     * 创建演出的订单
     *
     * @param userId
     * @param addressId
     * @param orderPrice
     * @param list
     */
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public String createPreformaceOrder(Integer userId, Integer addressId, BigDecimal orderPrice, Integer performanceId, List<OdrOrderItems> list) {
        //ResponseParameter responseParameter = new ResponseParameter();
        //根据演出id查询演出信息
        PfmPerformanceTotal pfmPerformanceTotal = pfmPerformanceTotalMapper.findByValid(performanceId);
        if (pfmPerformanceTotal == null) {//没有这个演出
            logger.warn("根据id查询不到演出:{}", performanceId);
            throw new CustomBizException(PERFORMANCE_UNABLE_BUY);
        }
        if (list.size() == 0) {
            logger.warn("创建订单购买项不能为空");
            throw new CustomBizException(NO_ITEMS);
        }
        //根据票的id查询场地的id
        Integer singleId = pfmPerformanceTicketMapper.findSingleIdByTicketId(list.get(0).getGoodsId());
        String sn = createOrderSn(userId.toString());
        OdrOrder odrOrder = new OdrOrder();
        odrOrder.setCreateTime(new Date());
        odrOrder.setOrderImageUrl(pfmPerformanceTotal.getPfmSquareImageUrl());//将演出信息的图片 插入到订单的image
        CfgRegion cfgRegion = cfgRegionMapper.selectByPrimaryKey(pfmPerformanceTotal.getCityId());
        odrOrder.setOrderCity(cfgRegion == null ? "" : cfgRegion.getName());//将演出信息的城市插入到订单city中
        odrOrder.setUserId(userId);
        odrOrder.setOrderDeliveryAddressId(addressId);
        odrOrder.setOrderName(pfmPerformanceTotal.getPerformanceTitle());
        odrOrder.setOrderPrice(orderPrice);
        odrOrder.setOrderSn(sn);
        odrOrder.setOrderStatus(Constant.APPLY);
        odrOrder.setBusinessId(singleId);
        odrOrder.setBusinessType(Constant.PERFORMANCE);
        odrOrder.setPostage(Integer.parseInt(Constant.CONFIGMAP.get("postage")));
        odrOrder.setDeleted(false);//未删除
        odrOrder.setOrderPlaceTime(new Date());//下单时间
        odrOrder.setOrderExpireTime(DateUtil.addMinutes(new Date(), Integer.parseInt(Constant.CONFIGMAP.get("payMinute"))));//订单未支付过期时间
        odrOrder.setUpdateTime(new Date());
        odrOrder.setOrderMemo(null);//订单备注
        odrOrder.setOrderPayChannel(null);//支付渠道5
        odrOrder.setOrderPayTime(null);//支付时间
        Integer count = odrOrderMapper.insertSelective(odrOrder);
        //统计总金额
        BigDecimal sumOrderPrice = new BigDecimal(0);
        for (OdrOrderItems odrOrderItems1 : list) {
            Integer ticketId = odrOrderItems1.getGoodsId();//订单详细的商品id就是票的id
            //根据id查询票
            PfmPerformanceTicket pfmPerformanceTicket = pfmPerformanceTicketMapper.selectByPrimaryKey(ticketId);
            BigDecimal price = pfmPerformanceTicket.getPfmTicketPrice();//查询出来的票的价格
            Integer number = odrOrderItems1.getGoodsTotalCount();//购买的数量
            OdrOrderItems odrOrderItems = new OdrOrderItems();
            odrOrderItems.setOrderId(odrOrder.getId());//订单Id
            odrOrderItems.setGoodsId(ticketId);//商品id
            odrOrderItems.setGoodsType(Constant.PERFORMANCE);//商品类型
            odrOrderItems.setGoodsName(pfmPerformanceTicket.getPfmTicketName());//商品名
            odrOrderItems.setGoodsPrice(price);//商品单价
            BigDecimal totalAmount = price.multiply(new BigDecimal(number));//算出总价
            odrOrderItems.setGoodsTotalAmount(totalAmount);//商品总价
            odrOrderItems.setGoodsTotalCount(number);//商品总的数量
            odrOrderItems.setGoodsRemainCount(odrOrderItems1.getGoodsTotalCount());//商品未取票数量
            odrOrderItems.setGoodsMemo(odrOrderItems1.getGoodsMemo());
            odrOrderItems.setCreateTime(new Date());
            odrOrderItemsMapper.insertSelective(odrOrderItems);

            Integer pfmTicketCount = pfmPerformanceTicket.getPfmTicketCount();//总库存
            Integer pfmTicketLockSum = pfmPerformanceTicket.getPfmTicketLockSum() == null ? 0 : pfmPerformanceTicket.getPfmTicketLockSum();//锁定库存

            //判断当前可用库存 总的预期-锁定的库存(锁定包括已售和锁定的)
            logger.info("创建演出订单= 总的数量为:{},锁定的库存为:{}", pfmTicketCount, pfmTicketLockSum);
            Integer sum = pfmTicketCount - pfmTicketLockSum;
            if (sum >= number) {//如果还有库存
                PfmPerformanceTicket ticket = new PfmPerformanceTicket();
                ticket.setId(ticketId);//票的id
                ticket.setPfmTicketLockSum(pfmTicketLockSum + number);
                logger.info("创建演出订单= 商品id:{},加上锁定库存为:{} ", ticketId, pfmTicketLockSum + number);
                pfmPerformanceTicketMapper.updateByPrimaryKeySelective(ticket);
            } else {
                //提示数量不够
                logger.warn("商品的库存不够: 商品id:{},购买数量:{},可购买总数量:{}", ticketId, number, sum);
                throw new CustomBizException(NUMBER_INSUFFICIENT);
            }
            //将每次的价格 累加
            sumOrderPrice = sumOrderPrice.add(totalAmount);
        }
        //将价格加上运费
        sumOrderPrice = sumOrderPrice.add(new BigDecimal(odrOrder.getPostage()));
        //如果算出来的价格不等于传递过来的总价格
        if (sumOrderPrice.compareTo(odrOrder.getOrderPrice()) != 0) {
            logger.warn("计算出来的价格不等于传递过来的总价格 odrOrder id:{}", odrOrder.getId());
            odrOrder.setOrderPrice(sumOrderPrice);
            odrOrderMapper.updateByPrimaryKeySelective(odrOrder);
            mailTools.SendMail("计算出来的价格不等于传递过来的总价", "传递的价格:" + orderPrice + ",订单号:" + odrOrder.getId());
        }
        return sn;
    }

    /**
     * 创建订单
     *
     * @param userId
     * @param addressId
     * @param orderPrice
     * @param list
     */
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public String createOrder(Integer userId, Integer addressId, BigDecimal orderPrice, Integer crowdfundingId, List<OdrOrderItems> list) {
        //ResponseParameter responseParameter = new ResponseParameter();
        //根据众筹id查询众筹信息
        Crowdfunding crowdfunding = cfiConcertCrowdfundingSingalMapper.findAllowedBuyCrowdfundingByCrowdfundingId(crowdfundingId);
        if (crowdfunding == null) {//没有这个众筹
            logger.warn("根据id查询不到众筹:{}", crowdfundingId);
            throw new CustomBizException(CROWDFUNDING_UNABLE_BUY);
        }
        if (computeTimestamp(crowdfunding.getCrowdfundingEndTime(), new Date()) == 0) {//如果 时间已结束
            throw new CustomBizException(CROWDFUNDING_UNABLE_BUY);
        }
        if (computeTimestamp(new Date(), crowdfunding.getCrowdfundingStartTime()) == 0) {//如果 时间还未开始
            throw new CustomBizException(CROWDFUNDING_PREPARE);
        }
        if (list.size() == 0) {
            logger.warn("创建订单购买项不能为空");
            throw new CustomBizException(NO_ITEMS);
        }
        String sn = createOrderSn(userId.toString());
        OdrOrder odrOrder = new OdrOrder();
        odrOrder.setOrderImageUrl(crowdfunding.getAppSquareImageUrl());//将众筹的正方形信息的图片 插入到订单的image
        odrOrder.setOrderCity(crowdfunding.getCity());//将演出信息的城市插入到订单city中
        odrOrder.setCreateTime(new Date());
        odrOrder.setUserId(userId);
        odrOrder.setOrderDeliveryAddressId(addressId);
        odrOrder.setOrderName(crowdfunding.getCrowdfundingTitle());
        odrOrder.setOrderPrice(orderPrice);
        odrOrder.setOrderSn(sn);
        odrOrder.setOrderStatus(Constant.APPLY);
        odrOrder.setBusinessId(crowdfunding.getId());
        odrOrder.setBusinessType(Constant.CROWDFUNDING);
        odrOrder.setPostage(Integer.parseInt(Constant.CONFIGMAP.get("postage")));
        odrOrder.setDeleted(false);//未删除
        odrOrder.setOrderPlaceTime(new Date());//下单时间
        odrOrder.setOrderExpireTime(DateUtil.addMinutes(new Date(), Integer.parseInt(Constant.CONFIGMAP.get("payMinute"))));//订单未支付过期时间
        odrOrder.setUpdateTime(new Date());
        odrOrder.setOrderMemo(null);//订单备注
        odrOrder.setOrderPayChannel(null);//支付渠道
        odrOrder.setOrderPayTime(null);//支付时间
        Integer count = odrOrderMapper.insertSelective(odrOrder);
        //统计总金额
        BigDecimal sumOrderPrice = new BigDecimal(0);
        for (OdrOrderItems odrOrderItems1 : list) {
            Integer payBackId = odrOrderItems1.getGoodsId();//订单详细的商品id就是回报id
            //根据id查询回报
            CfiConcertCrowdfundingPayBack cfiConcertCrowdfundingPayBack = cfiConcertCrowdfundingPayBackMapper.selectByPrimaryKey(payBackId);
            BigDecimal price = cfiConcertCrowdfundingPayBack.getPayBackPrice();
            Integer number = odrOrderItems1.getGoodsTotalCount();
            OdrOrderItems odrOrderItems = new OdrOrderItems();
            odrOrderItems.setOrderId(odrOrder.getId());//订单Id
            odrOrderItems.setGoodsId(payBackId);//商品id
            odrOrderItems.setGoodsType(Constant.CROWDFUNDING);//商品类型
            odrOrderItems.setGoodsName(cfiConcertCrowdfundingPayBack.getPayBackName());//商品名
            odrOrderItems.setGoodsPrice(price);//商品单价
            BigDecimal totalAmount = price.multiply(new BigDecimal(number));
            odrOrderItems.setGoodsTotalAmount(totalAmount);//商品总价
            odrOrderItems.setGoodsTotalCount(number);//商品总的数量
            odrOrderItems.setGoodsRemainCount(odrOrderItems1.getGoodsTotalCount());//商品未取票数量
            odrOrderItems.setGoodsMemo(odrOrderItems1.getGoodsMemo());
            odrOrderItems.setCreateTime(new Date());
            odrOrderItemsMapper.insertSelective(odrOrderItems);
            Integer payBackSum = cfiConcertCrowdfundingPayBack.getPayBackSum();
            Integer payBackLockedSum = cfiConcertCrowdfundingPayBack.getPayBackLockedSum() == null ? 0 : cfiConcertCrowdfundingPayBack.getPayBackLockedSum();
            //判断当前可用库存 总的预期-锁定的库存(锁定包括已售和锁定的)
            logger.info("创建订单= 总的预期数量为:{},锁定的库存为:{}", payBackSum, payBackLockedSum);
            Integer sum = payBackSum - payBackLockedSum;
            if (sum >= number) {//如果还有库存
                CfiConcertCrowdfundingPayBack updatePayBack = new CfiConcertCrowdfundingPayBack();
                updatePayBack.setId(cfiConcertCrowdfundingPayBack.getId());
                updatePayBack.setPayBackLockedSum(payBackLockedSum + number);
                logger.info("创建订单= 商品id:{},加上锁定库存为:{} ", payBackId, payBackLockedSum + number);
                cfiConcertCrowdfundingPayBackMapper.updateByPrimaryKeySelective(updatePayBack);
            } else {
                //提示数量不够
                logger.warn("商品的库存不够: 商品id:{},购买数量:{},可购买总数量:{}", payBackId, number, sum);
                throw new CustomBizException(NUMBER_INSUFFICIENT);
            }
            //将每次的价格 累加
            sumOrderPrice = sumOrderPrice.add(totalAmount);
        }
        //将价格加上运费
        sumOrderPrice = sumOrderPrice.add(new BigDecimal(odrOrder.getPostage()));
        //如果算出来的价格不等于传递过来的总价格
        if (sumOrderPrice.compareTo(odrOrder.getOrderPrice()) != 0) {
            logger.warn("计算出来的价格不等于传递过来的总价格 odrOrder id:{}", odrOrder.getId());
            odrOrder.setOrderPrice(sumOrderPrice);
            odrOrderMapper.updateByPrimaryKeySelective(odrOrder);
            mailTools.SendMail("计算出来的价格不等于传递过来的总价", "传递的价格:" + orderPrice + ",订单号:" + odrOrder.getId());
        }
        return sn;
    }

    /**
     * 删除订单
     *
     * @param userId
     * @param orderSn
     * @return
     */
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public boolean delectOrder(Integer userId, String orderSn) {
        OdrOrder order = odrOrderMapper.findOdrOrderByOderSn(orderSn);
        if (order != null) {
            if (order.getUserId().equals(userId)) {
                if (Constant.APPLY.equals(order.getOrderStatus())) {//如果该订单是待支付
                    logger.info("取消订单 orderSn:{}", order.getOrderSn());
                    OdrOrder updateOrder = new OdrOrder();
                    updateOrder.setId(order.getId());
                    updateOrder.setOrderStatus(INVALID);
                    odrOrderMapper.updateByPrimaryKeySelective(updateOrder);
                    //根据订单id查询订单的详细
                    List<OdrOrderItems> odrOrderItemses = odrOrderItemsMapper.findOdrOrderItemsByOrder(order.getId());
                    for (OdrOrderItems orderItems : odrOrderItemses) {
                        logger.info("订单的购买项=id:{}", orderItems.getId());
                        switch (orderItems.getGoodsType()) {
                            case Constant.PERFORMANCE:
                                PfmPerformanceTicket pfmPerformanceTicket = pfmPerformanceTicketMapper.selectByPrimaryKey(orderItems.getGoodsId());
                                //获取锁定的回报
                                Integer ticketLockSum = pfmPerformanceTicket.getPfmTicketLockSum() == null ? 0 : pfmPerformanceTicket.getPfmTicketLockSum();
                                Integer updateTicketLockSum = ticketLockSum - orderItems.getGoodsTotalCount();//释放库存
                                logger.info("回收演唱会票的订单,回收库存=票id为:{},票锁定数量:{},票待解锁数量为:{},回收之后的锁定数量为:{}", pfmPerformanceTicket.getId(), pfmPerformanceTicket.getPfmTicketLockSum(), orderItems.getGoodsTotalCount(), updateTicketLockSum);
                                //回收锁定的库存
                                PfmPerformanceTicket updatePfmPerformanceTicket = new PfmPerformanceTicket();
                                updatePfmPerformanceTicket.setId(pfmPerformanceTicket.getId());
                                updatePfmPerformanceTicket.setPfmTicketLockSum(updateTicketLockSum);
                                pfmPerformanceTicketMapper.updateByPrimaryKeySelective(updatePfmPerformanceTicket);
                                break;
                            case Constant.CROWDFUNDING:
                                //根据订单详细的商品id查询回报信息
                                CfiConcertCrowdfundingPayBack cfiConcertCrowdfundingPayBack = cfiConcertCrowdfundingPayBackMapper.selectByPrimaryKey(orderItems.getGoodsId());
                                Integer payBackLockedSum = cfiConcertCrowdfundingPayBack.getPayBackLockedSum() == null ? 0 : cfiConcertCrowdfundingPayBack.getPayBackLockedSum();//获取锁定的回报
                                Integer updatePayBackLockedSum = payBackLockedSum - orderItems.getGoodsTotalCount();
                                logger.info("回收众筹的订单,回收库存=回报id为:{},回报锁定数量:{},回报待解锁数量为:{},回收之后的锁定数量为:{}", cfiConcertCrowdfundingPayBack.getId(), cfiConcertCrowdfundingPayBack.getPayBackLockedSum(), orderItems.getGoodsTotalCount(), updatePayBackLockedSum);
                                //回收锁定的库存
                                CfiConcertCrowdfundingPayBack newcfiConcertCrowdfundingPayBack = new CfiConcertCrowdfundingPayBack();
                                newcfiConcertCrowdfundingPayBack.setId(cfiConcertCrowdfundingPayBack.getId());
                                newcfiConcertCrowdfundingPayBack.setPayBackLockedSum(updatePayBackLockedSum);
                                cfiConcertCrowdfundingPayBackMapper.updateByPrimaryKeySelective(newcfiConcertCrowdfundingPayBack);
                                break;
                            default:
                                logger.warn("订单回收商品类型不对,订单购买项ID:{}", orderItems.getId());
                                mailTools.SendMail("订单回收商品类型不对", "订单购买项ID:" + orderItems.getId());
                                break;
                        }
                    }
                } else {
                    //如果是 过期 成功  退款成功 可以删除订单
                    if (REFUND_COMPLETED.equals(order.getOrderStatus()) || INVALID.equals(order.getOrderStatus()) || COMPLETED.equals(order.getOrderStatus())) {
                        logger.info("删除订单 orderSn:{}", order.getOrderSn());
                        OdrOrder updateOrder = new OdrOrder();
                        updateOrder.setId(order.getId());
                        updateOrder.setDeleted(true);
                        odrOrderMapper.updateByPrimaryKeySelective(updateOrder);
                    }
                }
                return true;
            }
        }
        return false;
    }


    /**
     * 根据用户和状态返回订单列表
     *
     * @param userId
     * @param status
     * @param page
     * @param count
     * @return
     */
    public List<Map<String, Object>> getOrderByUserIdAndStatus(Integer userId, String status, Integer page, Integer
            count) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        Integer start = (page - 1) * count;
        List<OdrOrder> odrOrders = odrOrderMapper.findOdrOrderListByUserId(userId, status, new Date(), start, count);
        for (OdrOrder odrOrder : odrOrders) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("orderId", odrOrder.getId());//订单id
            resultMap.put("orderSn", odrOrder.getOrderSn());//订单号
            // resultMap.put("businessId", odrOrder.getBusinessId());//商业ID
            resultMap.put("businessType", odrOrder.getBusinessType());//商业类型
            resultMap.put("orderImageUrl", odrOrder.getOrderImageUrl());
            resultMap.put("orderCity", odrOrder.getOrderCity());
            resultMap.put("orderTitle", odrOrder.getOrderName());
            resultMap.put("sumPrice", odrOrder.getOrderPrice().subtract(new BigDecimal(odrOrder.getPostage())));
            resultMap.put("sumPriceAndPostage", odrOrder.getOrderPrice());
            resultMap.put("postage", odrOrder.getPostage());
            resultMap.put("orderTime", odrOrder.getCreateTime());
            resultMap.put("requestStatus", status);
            if (Constant.APPLY.equals(status.trim())) {//如果查询的待支付
                resultMap.put("orderStatus", ODR_STATUS_MAP.get(Constant.APPLY));//订单状态
                resultMap.put("orderStatusEn", Constant.APPLY);//订单状态
            } else {
                resultMap.put("orderStatus", ODR_STATUS_MAP.get(Constant.APPLY.equals(odrOrder.getOrderStatus()) ? Constant.INVALID : odrOrder.getOrderStatus()));//订单状态
                resultMap.put("orderStatusEn", Constant.APPLY.equals(odrOrder.getOrderStatus()) ? Constant.INVALID : odrOrder.getOrderStatus());//订单状态
            }
            //计算订单还有多久失效
            Long beforeCloseTime = computeTimestamp(odrOrder.getOrderExpireTime(), new Date());
            resultMap.put("beforeCloseTime", beforeCloseTime);
            //根据订单id查询订单明细
            StringBuffer stringBuffer = new StringBuffer();
            List<OdrOrderItems> OdrOrderItemss = odrOrderItemsMapper.findOdrOrderItemsByOrder(odrOrder.getId());
            for (OdrOrderItems odrOrderItems : OdrOrderItemss) {
                stringBuffer.append("￥" + odrOrderItems.getGoodsPrice() + "×" + odrOrderItems.getGoodsTotalCount() + ";");
            }
            resultMap.put("payDetail", stringBuffer);
            //根据众筹id查询众筹
//            CfiConcertCrowdfundingSingal cfiConcertCrowdfundingSingal = cfiConcertCrowdfundingSingalMapper.selectByPrimaryKey(odrOrder.getCrowdfundingId());
//            if (cfiConcertCrowdfundingSingal != null) {
//                resultMap.put("statusZh", Constant.CFI_STATUS_MAP.get(cfiConcertCrowdfundingSingal.getStatus().toUpperCase()));//众筹状态
//                resultMap.put("statusEn", cfiConcertCrowdfundingSingal.getStatus().toUpperCase());//众筹状态
//            }
            //取消在订单中显示众筹的状态
//            resultMap.put("statusZh", "");//众筹状态
//            resultMap.put("statusEn", "");//众筹状态
            resultList.add(resultMap);
        }
        return resultList;
    }

    /**
     * 根订单号和用户id返回订单
     *
     * @param orderSn
     * @param userId
     * @return
     */
    public OdrOrder getOdrOrder(String orderSn, Integer userId) {
        OdrOrder odrOrder = odrOrderMapper.findOdrOrderByOderSn(orderSn);
        if (odrOrder != null && userId.equals(odrOrder.getUserId())) {
            return odrOrder;
        }
        return null;
    }

    /**
     * 根据订单号查询订单详细
     *
     * @param orderSn
     * @param userId
     * @return
     */
    public Map<String, Object> getOrderByOrderSnAndUserId(String orderSn, Integer userId) {
        Map<String, Object> resultMap = new HashMap<>();
        OdrOrder odrOrder = odrOrderMapper.findOdrOrderByOderSn(orderSn);
        if (odrOrder != null && odrOrder.getUserId().equals(userId)) {//如果不等于空 并且是userId的订单
            resultMap.put("orderSn", odrOrder.getOrderSn());//订单号
            resultMap.put("businessId", odrOrder.getBusinessId());//商业ID
            //判断类型是是否是演出 需要获取到他的演出主表的id
            if (PERFORMANCE.equals(odrOrder.getBusinessType())) {
                Integer pfmId = pfmPerformanceSingleMapper.findpfmIdById(odrOrder.getBusinessId());
                resultMap.put("businessId", pfmId);//商业ID
            }
            resultMap.put("businessType", odrOrder.getBusinessType());//商业类型
            resultMap.put("orderImageUrl", odrOrder.getOrderImageUrl());
            resultMap.put("orderCity", odrOrder.getOrderCity());
            resultMap.put("orderTitle", odrOrder.getOrderName());
            resultMap.put("sumPrice", odrOrder.getOrderPrice().subtract(new BigDecimal(odrOrder.getPostage())));
            resultMap.put("sumPriceAndPostage", odrOrder.getOrderPrice());
            resultMap.put("postage", odrOrder.getPostage());
            resultMap.put("orderTime", odrOrder.getCreateTime());
            resultMap.put("payTime", odrOrder.getOrderPayTime() == null ? "" : odrOrder.getOrderPayTime());
            //查询支付渠道
            if (odrOrder.getOrderPayChannel() != null) {
                CfgPayment cfgPayment = cfgPaymentMapper.selectByPrimaryKey(odrOrder.getOrderPayChannel());
                resultMap.put("payChannel", cfgPayment.getPayment());//支付渠道
            } else {
                resultMap.put("payChannel", "");//支付渠道
            }
            //计算订单还有多久失效
            Long beforeCloseTime = computeTimestamp(odrOrder.getOrderExpireTime(), new Date());
            resultMap.put("beforeCloseTime", beforeCloseTime);
            //根据订单id查询订单明细
            StringBuffer stringBuffer = new StringBuffer();
            List<OdrOrderItems> OdrOrderItemss = odrOrderItemsMapper.findOdrOrderItemsByOrder(odrOrder.getId());
            for (OdrOrderItems odrOrderItems : OdrOrderItemss) {
                stringBuffer.append("￥" + odrOrderItems.getGoodsPrice() + "×" + odrOrderItems.getGoodsTotalCount() + ";");
            }
            resultMap.put("payDetail", stringBuffer);

            if (Constant.CROWDFUNDING.equals(odrOrder.getBusinessType())) {//如果是众筹的订单显示众筹的状态
                //根据众筹id查询众筹状态
                CfiConcertCrowdfundingSingal cfiConcertCrowdfundingSingal = cfiConcertCrowdfundingSingalMapper.selectByPrimaryKey(odrOrder.getBusinessId());
                if (cfiConcertCrowdfundingSingal != null) {
                    resultMap.put("statusZh", Constant.CFI_STATUS_MAP.get(cfiConcertCrowdfundingSingal.getStatus().toUpperCase()));//众筹状态
                    resultMap.put("statusEn", cfiConcertCrowdfundingSingal.getStatus().toUpperCase());//众筹状态
                }
            } else if (Constant.PERFORMANCE.equals(odrOrder.getBusinessType())) {//如果是演出
                //查询演出的状态
                Integer pfmId = pfmPerformanceSingleMapper.findpfmIdById(odrOrder.getBusinessId());
                String status = pfmPerformanceTotalMapper.findStatusById(pfmId);
                logger.debug(status);
                if (status != null) { //状态(EDIT/PROCESS/CANCEL)
                    resultMap.put("statusZh", Constant.PFM_STATUS_MAP.get(status.toUpperCase()));//众筹状态
                    resultMap.put("statusEn", status.toUpperCase());//众筹状态
                }
            }
            //获取订单的地址
            UsrDeliveryAddress usrDeliveryAddress = usrDeliveryAddressMapper.selectByPrimaryKey(odrOrder.getOrderDeliveryAddressId());
            resultMap.put("addressId", usrDeliveryAddress.getId());//地址id
            resultMap.put("person", usrDeliveryAddress.getDeliveryPerson());//收货人
            resultMap.put("mobile", usrDeliveryAddress.getDeliveryMobile()); //收货人手机
            resultMap.put("zipCode", usrDeliveryAddress.getZipCode() == null ? "" : usrDeliveryAddress.getZipCode());//邮编
            resultMap.put("address", usrDeliveryAddress.getDeliveryAddress());//收货地址
            resultMap.put("isDefault", usrDeliveryAddress.getIsDefault() ? 1 : 0);//是否默认
            resultMap.put("province", usrDeliveryAddress.getProvince());//省
            resultMap.put("city", usrDeliveryAddress.getCity());//市
            resultMap.put("district", usrDeliveryAddress.getDistrict() == null ? "" : usrDeliveryAddress.getDistrict());//区
            resultMap.put("road", usrDeliveryAddress.getRoad() == null ? "" : usrDeliveryAddress.getRoad());//道路
            resultMap.put("other", usrDeliveryAddress.getOther() == null ? "" : usrDeliveryAddress.getOther());//剩地址
            return resultMap;
        }
        return resultMap;
    }


    /**
     * 获取用户所有的票
     *
     * @param userId
     * @param page
     * @param count
     * @return
     */
    public List<Map<String, Object>> getTicketByUserId(Integer userId, Integer page, Integer count) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        Integer start = (page - 1) * count;
        List<OdrTicketInfo> odrTicketInfos = odrTicketInfoMapper.findOdrTicketInfoByUserId(userId, start, count);
        for (OdrTicketInfo odrTicketInfo : odrTicketInfos) {
            //OdrOrder odrOrder = odrOrderMapper.selectByPrimaryKey(odrTicketInfo.getOrderId());
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("id", odrTicketInfo.getId());
            resultMap.put("concertName", odrTicketInfo.getConcertName());//演唱会名字
            resultMap.put("ticketPrice", odrTicketInfo.getTicketPrice());
            resultMap.put("ticketName", odrTicketInfo.getTicketName());//票的名字
            resultMap.put("image", odrTicketInfo.getTicketImageUrl());//图片
            resultMap.put("ticketCreateTime", odrTicketInfo.getCreateTime());//创建日期
            resultMap.put("address", odrTicketInfo.getTicketUseAddress());//地址
            resultMap.put("fieldName", odrTicketInfo.getFieldName());//场地名字
            resultMap.put("status", odrTicketInfo.getTicketStatus());//票的状态   VALID：有效，USED：已使用，EXPIRED：已过期
            resultMap.put("businessId", odrTicketInfo.getBusinessId());//商业ID
            resultMap.put("businessType", odrTicketInfo.getBusinessType());//商业类型
            resultMap.put("businessSn", odrTicketInfo.getBusinessSn());//商业Sn
            resultList.add(resultMap);
        }
        return resultList;
    }


    /**
     * 获取单个票
     *
     * @param userId
     * @param id
     * @return
     */
    public Map<String, Object> getTicketById(Integer userId, Integer id) {
        OdrTicketInfo odrTicketInfo = odrTicketInfoMapper.selectByPrimaryKey(id);
        if (odrTicketInfo != null && userId.equals(odrTicketInfo.getUserId())) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("concertName", odrTicketInfo.getConcertName());//演唱会名字
            resultMap.put("ticketPrice", odrTicketInfo.getTicketPrice());
            resultMap.put("ticketName", odrTicketInfo.getTicketName());//票的名字
            resultMap.put("ticketCreateTime", odrTicketInfo.getCreateTime());//创建日期
            resultMap.put("address", odrTicketInfo.getTicketUseAddress());//地址
            resultMap.put("fieldName", odrTicketInfo.getFieldName());//场地名字
            resultMap.put("longitude", odrTicketInfo.getLongitude());//经度
            resultMap.put("latitude", odrTicketInfo.getLatitude());//纬度
            resultMap.put("seatInfo", odrTicketInfo.getTicketSeatInfo());//座位信息
            resultMap.put("status", odrTicketInfo.getTicketStatus());//票的状态   VALID：有效，USED：已使用，EXPIRED：已过期
            //resultMap.put("validCodeStatus", odrTicketInfo.getValidCodeStatus());//验证码状态，WAITING：尚未开启验证，VALID：有效，EXPIRED：已过期
            resultMap.put("ticketType", odrTicketInfo.getTicketType());//验票码类型
            //resultMap.put("ticketStatus", odrTicketInfo.getTicketStatus());//票据状态
            String md5Code = "0";
            if ("VALID".equals(odrTicketInfo.getTicketStatus())) {
                String validCode = odrTicketInfo.getTicketValidCode();
                String key = odrTicketInfo.getSecretKey();
                md5Code = Md5.encoderToString(validCode, key);
            }
            resultMap.put("ticketValidCode", odrTicketInfo.getTicketSerialNumber() + "_" + md5Code);//验票码
            return resultMap;
        } else {
            logger.info("票不存在或者票和UserID不对应，userId:{},票的UserId:{}", userId, odrTicketInfo == null ? null : odrTicketInfo.getUserId());
            return null;
        }
    }

//    /**
//     * 获取二维码  (直接显示二维码 不用单独获取)
//     *
//     * @param userId
//     * @param id
//     * @return
//     */
//
//    public String getQrcode(Integer userId, Integer id) {
//        OdrTicketInfo odrTicketInfo = odrTicketInfoMapper.selectByPrimaryKey(id);
//        if (odrTicketInfo != null && userId.equals(odrTicketInfo.getUserId())) {
//            String md5Code = "0";
//            //判断是否到了开始验票时间
//            Date ticketUseTime = odrTicketInfo.getTicketUseTime();
//            Long difference1 = DateUtil.computeTimestamp(new Date(), ticketUseTime);
//            if (difference1 == 0) {//还没有开始验票时间
//                throw new CustomBizException(TICKET_STATUS_MAP.get("WAITING"));
//            } else {
//                if ("WAITING".equals(odrTicketInfo.getTicketStatus())) {//如果是尚未验票
//                    odrTicketInfo.setTicketStatus("VALID");
//                    odrTicketInfo.setValidCodeStatus("VALID");
//
//                    OdrTicketInfo odrTicketInfoUpdate = new OdrTicketInfo();
//                    odrTicketInfoUpdate.setTicketStatus("VALID");
//                    odrTicketInfoUpdate.setValidCodeStatus("VALID");
//                    odrTicketInfoUpdate.setId(odrTicketInfo.getId());
//                    odrTicketInfoMapper.updateByPrimaryKeySelective(odrTicketInfoUpdate);
//                }
//            }
//            if (!"VALID".equals(odrTicketInfo.getTicketStatus())) {//票无效
//                throw new CustomBizException(TICKET_STATUS_MAP.get(odrTicketInfo.getTicketStatus()));
//            }
//            if (!"VALID".equals(odrTicketInfo.getValidCodeStatus())) {
//                throw new CustomBizException(TICKET_STATUS_MAP.get(odrTicketInfo.getValidCodeStatus()));
//            }
//            //将之前的时间加 二维码过期时间
//            Date date = new Date(Long.parseLong(odrTicketInfo.getSecretKey()));//老的时间
//            Integer ticketExpirationTime = Integer.valueOf(CONFIGMAP.get("ticketExpirationTime"));//二维码过期时间
//            Date date1 = DateUtil.addMinutes(date, ticketExpirationTime);//老的时间+二维码过期时间
//            Long difference = DateUtil.computeTimestamp(new Date(), date1);//等于0表示超时
//            String validCode = odrTicketInfo.getTicketValidCode();
//            String key = odrTicketInfo.getSecretKey();
//            if (difference == 0) {//如果是过期
//                key = String.valueOf(new Date().getTime());
//                //更新 key为最新时间
//                OdrTicketInfo odrTicketInfoUpdate = new OdrTicketInfo();
//                odrTicketInfoUpdate.setId(odrTicketInfo.getId());
//                odrTicketInfoUpdate.setSecretKey(key);
//                odrTicketInfoMapper.updateByPrimaryKeySelective(odrTicketInfoUpdate);
//            }
//            md5Code = Md5.encoderToString(validCode, key);
//            return odrTicketInfo.getTicketSerialNumber() + "_" + md5Code;//验票码
//        }
//        return null;
//    }

    /**
     * 扫描二维码
     *
     * @param Qrcod
     * @param userId
     * @param id
     */
    public Boolean scanQrcode(String Qrcod, Integer userId, Integer id) {
        //查询检票员二维码是否存在
        UsrTicketInspector usrTicketInspector = usrTicketInspectorMapper.findUsrTicketInspectorBySn(Qrcod);
        if (usrTicketInspector != null) {
            //查询票
            OdrTicketInfo odrTicketInfo = odrTicketInfoMapper.selectByPrimaryKey(id);
            //判断是否有票，票是否是当前用户的
            if (odrTicketInfo != null && userId.equals(odrTicketInfo.getUserId())) {
                if (!odrTicketInfo.getBusinessSn().equals(usrTicketInspector.getBusinessSn())) {
                    logger.info("验票员的场地与票上的场地SN不一致,票的SN:{},验票员的SN:{}", odrTicketInfo.getBusinessSn(), usrTicketInspector.getBusinessSn());
                    throw new CustomBizException(VERIFY_INVALID);
                }
                //如果票无效
                if (!"VALID".equals(odrTicketInfo.getTicketStatus())) {
                    throw new CustomBizException(TICKET_STATUS_MAP.get(odrTicketInfo.getTicketStatus()));
                }
                //判断是否到了开始验票时间
                Date ticketUseTime = odrTicketInfo.getTicketUseTime();
                Long difference1 = DateUtil.computeTimestamp(new Date(), ticketUseTime);
                if (difference1 == 0) {//还没有开始验票时间
                    throw new CustomBizException(TICKET_STATUS_MAP.get("WAITING"));
                }
                //成功
                //修改票为已使用状态并记录验票员
                OdrTicketInfo odrTicketInfoUpdate = new OdrTicketInfo();
                odrTicketInfoUpdate.setId(odrTicketInfo.getId());
                odrTicketInfoUpdate.setTicketStatus("USED");
                odrTicketInfoUpdate.setTicketInspectorId(usrTicketInspector.getId());
                odrTicketInfoUpdate.setTicketValidateTime(new Date());
                odrTicketInfoMapper.updateByPrimaryKeySelective(odrTicketInfoUpdate);
                return true;
            } else {
                logger.info("票不存在或者票和UserID不对应，userId:{},票的UserId:{}", userId, odrTicketInfo == null ? null : odrTicketInfo.getUserId());
            }
        }
        return false;
    }


    /**
     * 验票员效验二维码
     *
     * @param inspectorSn
     * @return
     */
    public Boolean checkQrcode(String inspectorSn, String Qrcode) {
        //效验验票员是否合法
        UsrTicketInspector usrTicketInspector = usrTicketInspectorMapper.findUsrTicketInspectorBySn(inspectorSn);
        if (usrTicketInspector == null) {
            logger.info("验票员不可用或者不存在");
            throw new CustomBizException(Constant.INSPECTOR_INVALID);
        }
        //检查验票员的crowdfunding_sn 是否 和二维码的 前四位合法
        if (Qrcode.length() <= 4) {
            throw new CustomBizException(Constant.QRCODE_INVALID);
        }
        if (!Qrcode.substring(0, 4).equals(usrTicketInspector.getBusinessSn())) {
            throw new CustomBizException(Constant.QRCODE_INVALID);
        }
        //分割 _  查询对应的票SN
        String ticketSnstr = Qrcode.substring(0, Qrcode.indexOf("_"));
        OdrTicketInfo odrTicketInfo = odrTicketInfoMapper.findOdrTicketInfoByTicketSerialNumber(ticketSnstr);
        if (odrTicketInfo != null) {
            String md5Code = "0";
            //检查票
            if (!"VALID".equals(odrTicketInfo.getTicketStatus())) {
                throw new CustomBizException(TICKET_STATUS_MAP.get(odrTicketInfo.getTicketStatus()));
            }
            //判断是否到了开始验票时间
            Date ticketUseTime = odrTicketInfo.getTicketUseTime();
            Long difference1 = DateUtil.computeTimestamp(new Date(), ticketUseTime);
            if (difference1 == 0) {//还没有开始验票时间
                throw new CustomBizException(TICKET_STATUS_MAP.get("WAITING"));
            }
            String validCode = odrTicketInfo.getTicketValidCode();
            String key = odrTicketInfo.getSecretKey();
            md5Code = Md5.encoderToString(validCode, key);
            String checkQrcode = odrTicketInfo.getTicketSerialNumber() + "_" + md5Code;
            if (checkQrcode.equals(Qrcode)) {
                //二维码成功
                //修改票为已使用状态并记录验票员
                OdrTicketInfo odrTicketInfoUpdate = new OdrTicketInfo();
                odrTicketInfoUpdate.setId(odrTicketInfo.getId());
                odrTicketInfoUpdate.setTicketStatus("USED");
                odrTicketInfoUpdate.setTicketInspectorId(usrTicketInspector.getId());
                odrTicketInfoUpdate.setTicketValidateTime(new Date());
                odrTicketInfoMapper.updateByPrimaryKeySelective(odrTicketInfoUpdate);
                return true;
            } else {
                throw new CustomBizException(QRCODE_INVALID);
            }
        }
        return false;
    }

    /**
     * 根据userId生成订单号
     *
     * @return
     */

    public String createOrderSn(String userId) {
        Date date = new Date();
        long time = date.getTime();
        return userId + time;
    }
}
